<template>
  <el-card>
    <el-form inline>
      <el-form-item>
        <el-input v-model="username" placeholder="用户名" />
      </el-form-item>

      <el-button type="primary" icon="el-icon-search" @click="search">查询</el-button>
      <el-button type="default" @click="resetSearch">清空</el-button>
    </el-form>

    <div style="margin: 20px 0">
      <el-button type="primary" @click="showAddUser">添 加</el-button>
      <el-button type="danger" @click="revomveUsers" :disabled="tableState.selectedIds.length === 0">批量删除</el-button>
    </div>

    <el-table border stripe :data="getPages" v-loading="listLoading" @selection-change="handleSelectionChange">

      <el-table-column type="selection" width="55" />

      <el-table-column type="index" label="序号" width="80" align="center" />

      <el-table-column prop="username" label="用户名" width="150" />
      <el-table-column prop="nickName" label="用户昵称" />
      <el-table-column prop="roleName" label="角色列表" width="200" />

      <el-table-column prop="gmtCreate" label="创建时间" width="180" />
      <el-table-column prop="gmtModified" label="更新时间" width="180" />

      <el-table-column label="操作" width="200" align="center" fixed="right">
        <template slot-scope="scope">
          <el-button icon="el-icon-user-solid" type="info" size="mini" title="分配角色" @click="showAssignRole(scope.row)" />
          <el-button icon="el-icon-edit-outline" type="primary" size="mini" title="修改用户"
            @click="showUpdateUser(scope.row)" />
          <el-button icon="el-icon-delete" style="margin-left:10px" type="danger" size="mini" title="删除用户"
            @click="removeUser(scope.row.id)" />
        </template>
      </el-table-column>
      <!-- <el-table-column label="操作" width="200" align="center" fixed="right">
        <template v-slot="{ row }">
          <el-button icon="el-icon-user-solid" type="info" size="mini" title="分配角色" />
          <el-button icon="el-icon-edit-outline" type="primary" size="mini" title="修改用户" />
          <el-button icon="el-icon-delete" style="margin-left:10px" type="danger" size="mini" title="删除用户"
            @click="removeUser(row.id)" />
        </template>
      </el-table-column> -->
    </el-table>

    <div class="block">
      <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="page"
        :page-sizes="[5, 10, 15]" :page-size="5" layout="prev, pager, next, jumper, ->, sizes, total" :total="total">
      </el-pagination>
    </div>

    <el-dialog :title="userState.user.id ? '修改用户' : '添加用户'" :visible.sync="userState.dialogUserVisible">
      <el-form ref="userFormRef" :model="userState.user" label-width="120px">
        <el-form-item label="用户名" prop="username">
          <el-input v-model="userState.user.username" />
        </el-form-item>
        <el-form-item label="用户昵称">
          <el-input v-model="userState.user.nickName" />
        </el-form-item>

        <el-form-item label="用户密码" v-if="!userState.user.id" prop="password">
          <el-input v-model="userState.user.password" />
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="cancel">取 消</el-button>
          <el-button type="primary" :loading="userState.userLoading" @click="addOrUpdate">确 定</el-button>
        </div>
      </template>
    </el-dialog>

    <el-dialog title="设置角色" :visible.sync="roleState.dialogRoleVisible" :before-close="resetRoleData">
      <el-form label-width="80px">
        <el-form-item label="用户名">
          <el-input disabled :value="userState.user.username"></el-input>
        </el-form-item>

        <el-form-item label="角色列表">
          <el-checkbox :indeterminate="roleState.isIndeterminate" v-model="roleState.checkAll"
            @change="handleCheckAllChange">全选</el-checkbox>
          <div style="margin: 15px 0;"></div>
          <el-checkbox-group v-model="roleState.userRoleIds" @change="handleCheckedChange">
            <el-checkbox v-for="role in roleState.allRoles" :key="role.id" :label="role.id">{{ role.roleName
            }}</el-checkbox>
          </el-checkbox-group>
        </el-form-item>
      </el-form>

      <template #footer>
        <el-button @click="assignRole" :loading="roleState.roleLoading" type="primary">保存</el-button>
        <el-button @click="resetRoleData">取消</el-button>
      </template>
    </el-dialog>
  </el-card>
</template>

<script>
export default {
  data() {
    return {
      getPages: [],
      username: "",
      searchUsername: "",
      page: 1, // 当前页码
      limit: 5, // 每页数量
      total: 0,
      listLoading: false,
      roleState: {
        dialogRoleVisible: false,
        roleLoading: false,
        checkAll: false,
        isIndeterminate: false,
        userRoleIds: [],
        allRoles: []
      },
      userState: {
        dialogUserVisible: false,
        userLoading: false,
        user: {
          username: '',
          nickName: '',
          password: ''
        },
      },
      tableState: {
        total: 0,
        users: [],
        selectedIds: []
      }

    }
  },
  methods: {
    // 获取页面数据开始
    async getUsers() {
      let page = this.page
      let limit = this.limit
      this.listLoading = true
      try {
        const result = await this.$API.user.getPageList(page, limit, { username: this.searchUsername })
        this.listLoading = false
        console.log(result)
        this.getPages = result.data.items
        this.total = result.data.total
        this.tableState.selectedIds = []
      } catch (error) {
        console.log(error)
      }

    },
    // 获取页面数据结束

    // 输入框搜索开始
    search() {
      this.searchUsername = this.username
      this.getUsers()
      this.username = ''

    },
    // 输入框搜索结束

    // 输入框清空开始
    resetSearch() {
      this.searchUsername = ''
      this.username = ''
      this.getUsers()
    },
    // 输入框清空结束

    // 分页开始
    handleSizeChange(val) {
      // console.log(`每页 ${val} 条`);
      this.limit = val
      this.getUsers()
    },
    handleCurrentChange(val) {
      // console.log(`当前页: ${val}`);
      this.page = val
      this.getUsers()
    },
    // 分页结束
    // 删除某个用户开始
    async removeUser(id) {
      try {
        await this.$API.user.removeById(id)
        console.log(id)
        this.getUsers()
      } catch (error) {
        console.log(error)
      }

    },
    // 删除某个用户结束

    // 显示添加用户的界面开始
    showAddUser() {
      this.userState.user = {
        username: '',
        nickName: '',
        password: ''
      }
      this.userState.dialogUserVisible = true
    },

    // 取消用户的保存或更新
    cancel() {
      this.userState.dialogUserVisible = false
      this.userState.user = {
        username: '',
        nickName: '',
        password: ''
      }
    },

    // 显示更新用户的界面
    showUpdateUser(user) {
      this.userState.user = { ...user }
      this.userState.dialogUserVisible = true
    },

    // 保存或者更新用户
    async addOrUpdate() {
      const { user } = this.userState
      this.userState.userLoading = true
      try {
        if (this.userState.user.id) {
          await this.$API.user.update(user)
        } else {
          await this.$API.user.add(user)
        }
        this.userState.userLoading = false
        this.$message({
          message: '保存成功',
          type: 'success'
        });
        this.userState.user = {
          username: '',
          nickName: '',
          password: ''
        }
        this.userState.dialogUserVisible = false
        this.getUsers()
      } catch (error) {
        this.userState.userLoading = false
      }
    },
    // 显示添加用户的界面结束

    // 批量删除开始
    // 列表选中状态发生改变的监听回调
    handleSelectionChange(selection) {
      this.tableState.selectedIds = selection.map(item => item.id)
    },

    async revomveUsers() {
      this.$confirm('此操作将永久删除该文件, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(async () => {
        await this.$API.user.removeUsers(this.tableState.selectedIds)
        this.$message({
          type: 'success',
          message: '删除成功!'
        });
        this.getUsers()
      }).catch(() => {
        this.$message({
          type: 'info',
          message: '已取消删除'
        });
      });
    },
    // 批量删除结束

    // 请求给用户进行角色授权
    async assignRole() {

      const userId = this.userState.user?.id
      const roleIds = this.roleState.userRoleIds.join(',')
      this.roleState.roleLoading = true

      try {
        await this.$API.user.assignRoles(userId, roleIds)
        this.roleState.roleLoading = false
        this.$message({
          message: '分配角色成功',
          type: 'success'
        })
        this.resetRoleData()
        this.getUsers()
      } catch (error) {
        console.log(error)
      }


    },

    // 重置用户角色的数据
    resetRoleData() {
      Object.assign(this.roleState, {
        dialogRoleVisible: false,
        allRoles: [],
        userRoleIds: [],
        isIndeterminate: false,
        checkAll: false
      })
    },
    // 全选勾选状态发生改变的监听
    handleCheckAllChange(value) {
      // 如果当前全选, userRoleIds就是所有角色id的数组, 否则是空数组
      this.roleState.userRoleIds = value ? roleState.allRoles.map(item => item.id) : []
      // 如果当前不是全选也不全不选时, 指定为false
      this.roleState.isIndeterminate = false
    },
    // 角色列表选中项发生改变的监听
    handleCheckedChange() {
      const { userRoleIds, allRoles } = this.roleState
      this.roleState.checkAll = userRoleIds.length === allRoles.length && allRoles.length > 0
      this.roleState.isIndeterminate = userRoleIds.length > 0 && userRoleIds.length < allRoles.length
    },

    // 显示指定角色的界面
    showAssignRole(user) {
      this.userState.user = user
      this.roleState.dialogRoleVisible = true
      this.getRoles()
    },
    // 异步获取用户的角色列表
    async getRoles() {
      const result = await this.$API.user.getRoles(this.userState.user?.id)
      console.log(result)
      const { allRolesList, assignRoles } = result.data
      this.roleState.allRoles = allRolesList
      this.roleState.userRoleIds = assignRoles.map(item => item.id)
      this.roleState.checkAll = allRolesList.length === assignRoles.length
      this.roleState.isIndeterminate = assignRoles.length > 0 && assignRoles.length < allRolesList.length
    }


  },

  mounted() {
    this.getUsers()
  }

}

</script>
<style lang="scss" scoped></style>